package com.wxapp.common.util.map;

import com.wxapp.common.util.check.CheckUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * @author lgl
 */
public class MapUtil {
    private static final Logger log = LoggerFactory.getLogger(MapUtil.class);

    private MapUtil() {
    }

    /**
     * object 转map
     * @return
     */
    public static List<Map<String, Object>> getListObjectToMap(List<Object> obs) {
        List<Map<String, Object>> result = new ArrayList<>();
        try {
            obs.parallelStream().forEach(s -> {
                Map<String, Object> map = new HashMap<>();
                Class<?> cla = s.getClass();
                Field[] fields = cla.getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
                    String keyName = field.getName();
                    Object value = null;
                    try {
                        value = field.get(cla);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                    if (value == null) {
                        value = "";
                    }
                    map.put(keyName, value);
                }
                result.add(map);
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }
    /**
     * map to object
     * @param map the map
     * @param clazz the Object class
     * @return the object
     */
    public static <T> T mapToObject(Map<String, String> map, Class<T> clazz) {
        if (CheckUtil.isNullMap(map)) {
            return null;
        }
        try {
            T instance =  clazz.getDeclaredConstructor().newInstance();
            Field[] fields = instance.getClass().getDeclaredFields();
            for (Field field : fields) {
                int modifiers = field.getModifiers();
                if (Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers)) {
                    continue;
                }
                boolean accessible = field.canAccess(field);
                field.setAccessible(true);
                Class<?> type = field.getType();
                if (type == Date.class) {
                    if (CheckUtil.isNotNullString(map.get(field.getName()))) {
                        field.set(instance, new Date(Long.valueOf(map.get(field.getName()))));
                    }
                } else if (type == Long.class) {
                    if (CheckUtil.isNotNullString(map.get(field.getName()))) {
                        field.set(instance, Long.valueOf(map.get(field.getName())));
                    }
                } else if (type == Integer.class) {
                    if (CheckUtil.isNotNullString(map.get(field.getName()))) {
                        field.set(instance, Integer.valueOf(map.get(field.getName())));
                    }
                } else if (type == Double.class) {
                    if (CheckUtil.isNotNullString(map.get(field.getName()))) {
                        field.set(instance, Double.valueOf(map.get(field.getName())));
                    }
                } else{
                    if (CheckUtil.isNotNullString(map.get(field.getName()))) {
                        field.set(instance, map.get(field.getName()));
                    }
                }
                field.setAccessible(accessible);
            }
            return instance;
        } catch (Exception e) {
            log.error("转换失败", e.getMessage());
            throw new RuntimeException("转换失败" + e.getMessage());
        }
    }
    /**
     * object to map
     * @param object the object
     * @return the map
     */
    public static Map<String, String> objectToMap(Object object) {
        if (object == null) {
            return null;
        }
        Map<String, String> map = new HashMap<>(16);
        Field[] fields = object.getClass().getDeclaredFields();
        try {
            for (Field field : fields) {
                boolean accessible = field.isAccessible();
                field.setAccessible(true);
                if (field.getType() == Date.class) {
                    Date date = (Date) field.get(object);
                    if (date != null) {
                        map.put(field.getName(), String.valueOf(date.getTime()));
                    }
                } else {
                    map.put(field.getName(), field.get(object) == null ? "" : field.get(object).toString());
                }
                field.setAccessible(accessible);
            }
        } catch (Exception e) {
            log.error("转换失败", e.getMessage());
            throw new RuntimeException("转换失败" + e.getMessage());
        }
        return map;
    }
}
